﻿using Levfier.GUI.Status;
using Levfier.Proccessors.Chains;
using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace Levfier.GUI.EditorControls.Chains
{
    /// <summary>
    /// プロセッサ接続に対応するGUIパーツ
    /// </summary>
    [Serializable]
    abstract public class LinkControl : Canvas, IDrawable, IStatusCreatable
    {
        /// <summary>
        /// IDの連番
        /// </summary>
        private static int totalId = 0;


        /// <summary>
        /// ID
        /// </summary>
        public string Id
        {
            get { return id; }
            set { this.id = value; }
        }

        /// <summary>
        /// 選択時の色
        /// </summary>
        protected readonly Brush selectedBrush = new SolidColorBrush(Color.FromArgb(0xFF, 0x00, 0xAA, 0xDE));

        /// <summary>
        /// 上流の移動体オブジェクト
        /// </summary>
        protected IMovable upper;

        /// <summary>
        /// 下流の移動体オブジェクト
        /// </summary>
        protected IMovable lower;

        /// <summary>
        /// 接続オブジェクト
        /// </summary>
        protected IChainable chain;

        /// <summary>
        /// 上流・下流の間にラインを生成する
        /// </summary>
        protected ILineCreatable lineCreater;

        /// <summary>
        /// ID
        /// </summary>
        private string id;

        /// <summary>
        /// コンストラクタ
        /// </summary>
        /// <param name="upper">キャンバス上で移動可能コントロール</param>
        /// <param name="lower">キャンバス上で移動可能コントロール</param>
        public LinkControl(IMovable upper, IMovable lower)
        {
            //プロセッサの接続処理
            this.upper = upper;
            this.lower = lower;

            //描画に関する処理
            this.Width = 5000;
            this.Height = 5000;

            this.id = "L" + DateTime.Now.ToString("yyyyMMddhhmmssfff") + totalId;
            totalId++;
        }

        /// <summary>
        /// 描画更新する
        /// </summary>
        public void Update()
        {
            //線を全部消す
            this.Children.Clear();

            //線を生成する
            IEnumerable<UIElement> elements = this.lineCreater.CreateLine(upper.GetCenterPosition(), lower.GetCenterPosition());

            //新規に生成した線を追加する
            foreach (UIElement element in elements)
            {
                this.Children.Add(element);
            }
        }

        /// <summary>
        /// 選択された時の動作
        /// 末端の子クラスで実装すること
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        abstract public void Select(object sender);

        /// <summary>
        /// 選択解除された時の動作
        /// 末端の子クラスで実装すること
        /// </summary>
        /// <param name="sender">イベント発生源</param>
        abstract public void Unselect(object sender);

        /// <summary>
        /// 自分自身を削除する
        /// </summary>
        abstract public IEnumerable<UIElement> Delete();

        /// <summary>
        /// ステータスを取得する
        /// </summary>
        /// <returns>ステータス</returns>
        public ControlStatus GetStatus()
        {
            ChainControlStatus status = new ChainControlStatus();

            //上流IDを格納する
            IStatusCreatable creater = this.upper as IStatusCreatable;

            if(null == creater)
            {
                return null;
            }
            status.UpperId = creater.GetStatus().Id;

            //下流IDを格納する
            creater = this.lower as IStatusCreatable;

            if (null == creater)
            {
                return null;
            }
            status.LowerId = creater.GetStatus().Id;

            //ステータスを設定する
            status.Name = "Chain";
            status.Id = this.id;

            return status;
        }
    }
}
